package main.java.juc;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 对比synchronized和Lock锁的区别
 * 1 synchronized 是内置的java关键字 lock锁是java的一个类
 * 2 synchronized 无法判断获取锁的状态 lock可以判断是否获取到了锁
 * 3 synchronized 会自动释放锁 lock必须要手动释放锁 如果不释放锁 会死锁
 * 4 synchronized 如果线程1 获得锁,线程2会等待 如果这时候线程1阻塞了 线程2会继续等
 *      但是lock锁 不一定会等待下去
 * 5 synchronized 是可重入锁 不可以中断，非公平 lock锁是可重入锁，可以判断锁，可以设置是否是公平锁还是非公平锁
 * 6 synchronized 适合锁少量的同步代码 lock适合锁大量的同步代码
 */
public class SaleTicketDemo02 {
    public static void main(String[] args) {
        Ticket2 ticket = new Ticket2();
        new Thread(()->{
            for(int i = 1;i<60;i++){
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for(int i = 1;i<60;i++){
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for(int i = 1;i<60;i++){
                ticket.sale();
            }
        },"C").start();
    }

}

class Ticket2{
    //属性 方法
    private int number = 50;
    /**
     * Lock三部曲
     * 1 new ReentrantLock
     * 2 lock.lock(); 加锁
     * 3 lock.unlock(); 解锁
     */
    Lock lock = new ReentrantLock();
    //卖票的方式
    public  void sale(){
        //加锁
        lock.lock();
        try {
            if(number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了第"+(50-(--number))+"票"+",还剩"+number+"张票.");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}
